package com.wg.elasticsearch.util;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Random;
import java.util.UUID;

/**
 * 字符操作
 *
 * @author QuCeng
 */
public class StringUtil extends StringUtils {

    private static final Logger logger = LoggerFactory.getLogger(StringUtil.class);

    private static char[] hexDigits = { '0', '1', '2', '3', '4', '5', '6', '7',
            '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

    public static final String DEFAULT_BOUND_SYMBOL = ","; // 平台默认连接符（1,2,3）

    public static final String DATA_STATISTICS_HASH_KEY_COMBINER = "&&"; // 统计数据REIDS KEY连接符

    /**
     * 字符串转换成double 数
     *
     * @param strDouble
     * @return
     */
    public static double toDouble(String strDouble) {
        if (strDouble == null || strDouble.trim().length() == 0) {
            return 0d;
        }

        try {
            return Double.parseDouble(strDouble);
        } catch (Exception e) {
            return 0d;
        }
    }

    /**
     * 字符串转换成int 数
     *
     * @param strInt
     * @return
     */
    public static int toInt(String strInt) {
        if (strInt == null || strInt.trim().length() == 0) {
            return 0;
        }

        try {
            return Integer.parseInt(strInt);
        } catch (Exception e) {
            return 0;
        }
    }

    /**
     * 把指定的数据转化为16进制格式的字符串
     *
     * @param data
     *            待转化的数据
     * @return 16进制表示的数据
     */
    public static String toHexString(byte[] data) {

        return toHexString(data, 0, data.length);
    }

    /**
     * 把指定的数据转化为16进制格式的字符串， 如toHexString({8,9,12,4},1,3) = "090C"
     *
     * @param data
     *            待转化的数据
     * @param beginIndex
     *            需转化的数据的起始索引
     * @param endIndex
     *            需转化的数据的结束索引
     * @return 16进制表示的数据
     */
    public static String toHexString(byte[] data, int beginIndex, int endIndex) {

        if (data == null || beginIndex < 0)
            return null;
        StringBuilder strBuilder = new StringBuilder();
        for (int i = beginIndex; i < endIndex; i++) {
            strBuilder.append(hexDigits[data[i] >>> 4 & 0xf]);
            strBuilder.append(hexDigits[data[i] & 0xf]);
        }
        return strBuilder.toString();
    }



    public static String trim(String str) {

        return str == null ? "" : str.trim();
    }

    public static String generateLoginToken() {
        String s = UUID.randomUUID().toString();

        return s.replaceAll("-", "");
    }

    /**
     * 规范化金额格式
     * 2个字符串（其实是数值），的和；如addAsDouble("8.00","3.00") = "11.00";
     *
     * @param firstStr
     * @param secStr
     * @return
     */
    public static String addAsDouble(String firstStr, String secStr) {
        double resultDoubleVal = 0.0;
        double firstDoubleVal = 0.0;
        double secDoubleVal = 0.0;
        String result = null;
        if (firstStr != null && !"".equals(firstStr)) {
            firstDoubleVal = Double.parseDouble(firstStr);
        }

        if (secStr != null && !"".equals(secStr)) {
            secDoubleVal = Double.parseDouble(secStr);
        }
        resultDoubleVal = firstDoubleVal + secDoubleVal;
        result = String.valueOf(resultDoubleVal);
        result = getUniversalFeeFormat(result);
        return result;
    }

    /**
     * 将字符串形式的金额统一起来，目前都显示2位小数点
     *
     * @param feeStr
     * @return
     */
    public static String getUniversalFeeFormat(String feeStr) {
        String resultStr = "";
        if (StringUtils.isBlank(feeStr))
            return "";

        int dotLoc = feeStr.indexOf(".");
        int length = feeStr.length();

        if (dotLoc == -1) {
            // 没有小数点，则补充2位
            resultStr = feeStr + ".00";
        } else if (dotLoc == 0) {
            // 没有小数点，如.2756或.1
            resultStr = "0" + feeStr;
            resultStr = getUniversalFeeFormat(resultStr);
        } else if (length - dotLoc == 2) {
            // 如3.4，将它转化为3.40
            resultStr = feeStr + "0";
        } else if (length - dotLoc == 3) {
            // 如3.40，不需要改变
            resultStr = feeStr;
        } else if (length - dotLoc > 3) {
            // 如3.14159265
            resultStr = feeStr.substring(0, dotLoc + 3);
        } else if (length - dotLoc == 1) {
            // 如312. 较少见，补充00
            resultStr = feeStr + "00";
        }

        return resultStr;
    }

    /**
     * 根据分隔符来分割数字串 example:"1-9",解析后结构就是[1,2,3,4,5,6,7,8,9], "1;2;4;5"
     * 分割后结果就是[1,2,4,5], 暂时只支持这两种格式的解析
     *
     * @param numArea
     * @return
     */
    public static String[] parseNumArea(String numArea) {
        String[] noArray;

        if (numArea.indexOf("-") > 0) {
            String[] nums = numArea.split("-");

            int first = Integer.parseInt(nums[0]);
            int last = Integer.parseInt(nums[1]);

            noArray = new String[last - first + 1];

            for (int i = 0, j = first; j <= last; i++, j++) {
                noArray[i] = j + "";
            }
        } else {
            noArray = StringUtils.split(numArea, ";");
        }

        return noArray;
    }

    /**
     * 根据输入的字符串，生成指定长度的随机字符串
     *
     * @param strPool
     * @param length
     * @return
     */
    public static String randomString(String strPool, int length) {
        if (strPool == null || length < 1) {
            return null;
        }

        Random randGen = new Random();
        char[] numbersAndLetters = (strPool).toCharArray();

        char[] randBuffer = new char[length];
        for (int i = 0; i < randBuffer.length; i++) {
            randBuffer[i] = numbersAndLetters[randGen.nextInt(strPool.length())];
        }
        return new String(randBuffer);
    }

    public static boolean isDoubleString(String inputStr) {
        try {
            Double.valueOf(inputStr);
        } catch (Exception e) {
            return false;
        }

        return true;
    }

    public static boolean isChinese(char c) {
        Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
        if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
                || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
                || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
                || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B
                || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
                || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS
                || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION) {
            return true;
        }

        return false;
    }

    /**
     * 模糊查询关键字转化加%
     * @param keyWord
     * @return
     */
    public static String getFuzzyQueryKeyWord(String keyWord) {
        if(StringUtils.isBlank(keyWord)) {
            return null;
        }
        StringBuffer sb = new StringBuffer();
        sb.append("%");
        for (char c : keyWord.toCharArray()) {
            sb.append(c + "%");
        }
        return sb.toString();
    }


    public static String getFuzzyQueryKeyWordOne(String keyWord) {
        if(StringUtils.isBlank(keyWord)) {
            return null;
        }
        StringBuffer sb = new StringBuffer();
        sb.append(keyWord).append("%");
        return sb.toString();
    }


    /**
     * 去除字符串末尾的逗号
     * @return
     */
    public static String removeLastComma(String s) {
        if(isBlank(s)) {
            return null;
        }

        return s.substring(0, s.length() - 1);
    }

    /**
     * 比较版本号大小
     * 当前的版本号 >= 作为参照的版本号，返回true
     * 当前的版本号 < 作为参照的版本号，或者版本号包含数字以外的字符 返回false
     * @param version 当前的版本号
     * @param referenceVersion 作为参照的版本号
     */
    public static boolean compareVersion(String version, String referenceVersion) {
        if(StringUtil.isBlank(version) || StringUtil.isBlank(referenceVersion)) {
            return false;
        }

        String[] v1 = version.split("\\.");
        String[] v2 = referenceVersion.split("\\.");
        int minLength = Math.min(v1.length, v2.length); // 取最小长度值

        int diff = 0;
        int idx = 0;
        while (idx < minLength && diff == 0) {
            // 都是数字
            if (isNumeric(v1[idx]) && isNumeric(v2[idx])) {
                diff = Integer.parseInt(v1[idx]) - Integer.parseInt(v2[idx]);
            } else {
                return false;
            }
            ++idx;
        }

        if (diff >= 0) {
            int maxLength = Math.max(v1.length, v2.length); // 取最大长度值
            if (maxLength > minLength) {
                boolean bool = false;
                for (int a=minLength; a<maxLength; a++) {
                    if (v1.length > v2.length) {
                        if (!isNumeric(v1[a])) {
                            return false;
                        }
                        bool = true;
                    } else {
                        if (!isNumeric(v2[a]) || !"0".equals(v2[a])) {
                            return false;
                        }

                        bool = true;
                    }
                }
                return bool;

            } else {
                return true;
            }
        } else {
            return false;
        }
    }


    public static String bigFirstWord(String word) {

        if(StringUtils.isEmpty(word) || word.length() == 0) {
            return "";
        }

        return word.substring(0, 1).toUpperCase() + word.substring(1, word.length());
    }

    /**
     * 金额 如果小数点后面是0 就不保留小数点 否则保留两位小数
     * @param num
     * @return
     */
    public static String moneyDecimalPoint(double num){
        if(num % 1.0 == 0){
            return String.valueOf((long)num);
        }
        return String.valueOf(num);
    }

    /**
     * 隐藏银行卡号
     * @param bankAccount
     * @return
     */
    public static String hideBankAccount(String bankAccount) {

        if(StringUtils.isBlank(bankAccount)) {
            return "";
        }
        if(bankAccount.length() <= 4) {
            return "****";
        }

        return produceStar(bankAccount.length() - 4) +
                bankAccount.substring(bankAccount.length()-4, bankAccount.length());
    }

    /**
     * 隐藏支付宝
     * @param zhifubao
     * @return
     */
    public static String hideZhifubao(String zhifubao) {
        if(StringUtils.isBlank(zhifubao)) {
            return "";
        }
        if(zhifubao.length() <= 7) {
            return "*******";
        }

        if(zhifubao.contains("@")) {
            if(zhifubao.substring(0 , zhifubao.indexOf("@")).length() < 3) {
                return "***" + zhifubao.substring(zhifubao.indexOf("@") , zhifubao.length());
            }
            return zhifubao.substring(0, 3)
                    + produceStar(zhifubao.length() - zhifubao.indexOf("@") - 3)
                    + zhifubao.substring(zhifubao.indexOf("@") , zhifubao.length());
        } else {
            return zhifubao.substring(0, 3)
                    +
                    produceStar(zhifubao.length() - 7)
                    +
                    zhifubao.substring(zhifubao.length() - 4, zhifubao.length());
        }

    }

    private static String produceStar(int length) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            sb.append("*");
        }
        return sb.toString();
    }

    /**
     * 组装银行和银行卡号
     * @param bankAccount
     * @return
     */
    public static String assembleBank(String bankAccount , String bankName) {

        if(StringUtils.isBlank(bankAccount)) {
            return "";
        }
        if(bankAccount.length() <= 4) {
            return bankName + " (" + bankAccount + ")";
        }

        return bankName +" (" + bankAccount.substring(bankAccount.length() - 4 , bankAccount.length()) + ")";
    }

    /**
     * 组装支付宝和支付宝号
     * @return
     */
    public static String assembleZhifubao(String zhifubaoAccount , String bankName) {

        return bankName +  " (" + hideZhifubao(zhifubaoAccount) + ")";
    }

    /**
     * 正则表达式匹配
     * @param content
     * @param regular
     * @return
     */
    public static Boolean regularMatching(String content , String regular) {

        if(null == content || null == regular) {
            return false;
        }

        return content.matches(regular);
    }

}
